package usecase;

import IBO.IAdresse;
import IBO.IClient;
import IBO.IClientParticulier;
import IBO.IClientSociete;
import IBO.ICodePostal;
import IBO.IForme;
import IBO.IIntervention;
import IUSECASE.IUC_GestionClient;
import bo.Adresse;
import bo.ClientParticulier;
import bo.ClientSociete;
import bo.CodePostal;
import bo.Forme;
import boerrors.AdresseMinimumMultiplicityException;
import boerrors.ClientParticulierInexistantException;
import boerrors.ClientSocieteInexistantException;
import boerrors.CodePostalInexistantException;
import boerrors.CodePostalMinimumMultiplicityException;
import boerrors.FormeInexistantException;
import boerrors.FormeMinimumMultiplicityException;
import boerrors.ZoneMinimumMultiplicityException;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
 
public class GestionClients extends UnicastRemoteObject implements IUC_GestionClient, Serializable { 

        private static GestionClients instance = null;    
   
        //*******************************************************************    
        //Constructeur du singleton    
        //*******************************************************************        
        public static GestionClients getInstance() throws RemoteException {        
                if(instance == null) instance = new GestionClients();        
                return instance;    
        }
   
        public GestionClients() throws RemoteException {
                super();
        }     
    
        //*******************************************************************
        //Convertir objet BO en objet IBO
        //*******************************************************************
        
        //Client particulier
        private Vector<IClientParticulier> convertCltPtoICltP(Vector<ClientParticulier> liste) {
                Vector<IClientParticulier> lstTmp = new Vector<IClientParticulier>();
                for (int i = 0; i < liste.size(); i++){
                    lstTmp.add((IClientParticulier) liste.get(i));}
                return lstTmp;
        }
        
        //Client societe
        private Vector<IClientSociete> convertCltStoICltS(Vector<ClientSociete> listeCP) {
                Vector<IClientSociete> lstTmp = new Vector<IClientSociete>();
                for (int i = 0; i < listeCP.size(); i++){
                    lstTmp.add((IClientSociete) listeCP.get(i));}
                return lstTmp;
        }
   
        //Forme
        private Vector<IForme> convertFrmtoIFrm(Vector<Forme> forme) {
                Vector<IForme> lstTmp = new Vector<IForme>();
                for (int i = 0; i < forme.size(); i++){lstTmp.add((IForme) forme.get(i));}
                return lstTmp;
        }   
   
        //Code Postal
        private Vector<ICodePostal> convertCPtoICP(Vector<CodePostal> listeCP) {
                Vector<ICodePostal> lstTmp = new Vector<ICodePostal>();
                for (int i = 0; i < listeCP.size(); i++){lstTmp.add((ICodePostal) listeCP.get(i));}
                return lstTmp;
        }
        
        //Code Postal
        private Vector<IAdresse> convertAdressetoIAdresse(Vector<Adresse> listeAdresseParClient) {
                Vector<IAdresse> lstTmp = new Vector<IAdresse>();
                for (int i = 0; i < listeAdresseParClient.size(); i++){lstTmp.add((IAdresse) listeAdresseParClient.get(i));}
                return lstTmp;
        }
  
        //*******************************************************************    
        //Methodes heritees    
        //*******************************************************************         

        //Client particulier
        public IClientParticulier creerClientParticulier(   String nom, String prenom, String rue, 
                                                            String numero, String[] codePostal, String telephone, 
                                                            String email, String TVA) throws RemoteException {
                try {
                    CodePostal cp = CodePostal.rechercherCodePostal(codePostal[1], codePostal[2]);
                    Adresse adresse = new Adresse(rue, numero, cp);
                    return new ClientParticulier(nom, prenom, adresse, telephone, email, TVA);
                } catch (CodePostalInexistantException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }
        
        public void modifierClientParticulier(  int idclient, String nom, String prenom, String rue, 
                                                String numero, String commune, String codePostal, String telephone, 
                                                String email, String TVA) 
                                                throws RemoteException {
                try {
                    //On recupere le client en fonction de son numero client
                    ClientParticulier client = bo.ListeClients.getInstance().rechercherParticulierIdClient(idclient);
                    ClientParticulier clone = (ClientParticulier) client.clone();
                    //On definit les attributs du clone
                    clone.setNom(nom);
                    clone.setPrenom(prenom);
                    clone.setNumeroTva(TVA);
                    clone.setTelephone(telephone);
                    clone.setEmail(email);
                    clone.getAdresse().setIdAdresse(client.getAdresse().getIdAdresse());
                    clone.getAdresse().setRue(rue);
                    clone.getAdresse().setNumero(numero);
                    clone.getAdresse().enregistrerCodePostalClone(CodePostal.rechercherCodePostal(codePostal, commune));
                    bo.ClientParticulier.modifier(clone);
                    //On reassigne les valeurs du clone au client.
                    client.setNom(clone.getNom());
                    client.setPrenom(clone.getPrenom());
                    client.setNumeroTva(clone.getNumeroTva());
                    client.setTelephone(clone.getTelephone());
                    client.setEmail(clone.getEmail());
                    client.getAdresse().setIdAdresse(clone.getAdresse().getIdAdresse());
                    client.getAdresse().setRue(clone.getAdresse().getRue());
                    client.getAdresse().setNumero(clone.getAdresse().getNumero());
                    client.getAdresse().enregistrerCodePostalClone(clone.getAdresse().getCodePostal());
                    //Modification terminee
                } catch (CodePostalInexistantException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ClientParticulierInexistantException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                } catch (AdresseMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                } catch (CodePostalMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ZoneMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                }
        }
        
        public Vector<IClientParticulier> listerClientsParticulier()throws RemoteException {
                    //Vector<IClientParticulier> listeTmp = convertCltPtoICltP(bo.ClientParticulier.lister());
                    Vector<IClientParticulier> listeTmp = convertCltPtoICltP(bo.ListeClients.getInstance().getListeClientParticulier());
                    return listeTmp;
        }

        public Vector<IClient> rechercher_NumClient(int numeroClient) throws RemoteException {
                Vector<IClient> lstClient = new Vector<IClient>();
                IClient cltTmp = (IClient)bo.ListeClients.getInstance().rechercherIdClient(numeroClient);
                if (cltTmp != null)
                    lstClient.add(cltTmp);
                return lstClient;
        }

        public Vector<IClientParticulier> rechercherClientParticulier_NumClient(int numeroClient) throws RemoteException {
                Vector<IClientParticulier> lstClientP = new Vector<IClientParticulier>();
                IClientParticulier cltTmp = (IClientParticulier)bo.ListeClients.getInstance().rechercherParticulierIdClient(numeroClient);
                if (cltTmp != null)
                    lstClientP.add(cltTmp);
                return lstClientP;
        }

        public Vector<IClientParticulier> rechercherClientParticulier_NomPrenom(String nom, String prenom) throws RemoteException {
                Vector<IClientParticulier> lstClientP = new Vector<IClientParticulier>();
                lstClientP = convertCltPtoICltP(bo.ListeClients.getInstance().rechercherParticulierNomPrenom(nom, prenom));
                return lstClientP;
        }

        public Vector<IClientParticulier> rechercherClientParticulier_Adresse(  String rue, String numero, String codePostal,
                                                                                String commune) throws RemoteException {
                try {
                    Vector<IClientParticulier> lstClientP = new Vector<IClientParticulier>();
                    lstClientP = convertCltPtoICltP(bo.ListeClients.getInstance().rechercherParticulierAdresse(rue, numero, codePostal, commune));
                    return lstClientP;
                } catch (AdresseMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                } catch (CodePostalMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }

        //Client societe
        public IClientSociete creerClientSociete(   String nom, String prenom, String rue, String numero, 
                                                    String[] codePostal, String telephone, String email, 
                                                    String numeroTVA, String nomSociete, String[] forme) 
                                                    throws RemoteException {
                try {
                    CodePostal cp = CodePostal.rechercherCodePostal(codePostal[1], codePostal[2]);
                    Adresse adresse = new Adresse(rue, numero, cp);
                    Forme frm = new Forme(Integer.parseInt(forme[0]), forme[1]);
                    IClientSociete clientS = new ClientSociete(nom, prenom, adresse, telephone, email, numeroTVA, nomSociete, frm);
                    return clientS;
                } catch (CodePostalInexistantException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }

        public void modifierClientSociete(  int idclient, String nom, String prenom, String rue, String numero, String commune,
                                            String codePostal, String telephone, String email, String numeroTVA, 
                                            String nomSociete, int idForme, String libelleForme) throws RemoteException {
                try {
                    //On recupere le client en fonction de son numero client
                    ClientSociete client = bo.ListeClients.getInstance().rechercherSocieteIdClient(idclient);

                    ClientSociete clone = (ClientSociete) client.clone();
                    //On definit les attributs du clone
                    clone.setNomSociete(nomSociete);
                    clone.setNumeroTva(numeroTVA);
                    clone.setNom(nom);
                    clone.setPrenom(prenom);
                    clone.setEmail(email);
                    clone.setTelephone(telephone);
                    clone.getAdresse().setIdAdresse(client.getAdresse().getIdAdresse());
                    clone.getAdresse().setRue(rue);
                    clone.getAdresse().setNumero(numero);
                    clone.getAdresse().enregistrerCodePostalClone(CodePostal.rechercherCodePostal(codePostal, commune));
                    clone.enregistrerFormeClone(new Forme(idForme, libelleForme));
                    //On insere les valeurs du clone dans la DB
                    bo.ClientSociete.modifier(clone);
                    //On reassigne les valeurs du clone au client.
                    client.setNomSociete(clone.getNomSociete());
                    client.setNumeroTva(clone.getNumeroTva());
                    client.setNom(clone.getNom());
                    client.setPrenom(clone.getPrenom());
                    client.setEmail(clone.getEmail());
                    client.setTelephone(clone.getTelephone());
                    client.getAdresse().setIdAdresse(clone.getAdresse().getIdAdresse());
                    client.getAdresse().setRue(clone.getAdresse().getRue());
                    client.getAdresse().setNumero(clone.getAdresse().getNumero());
                    client.getAdresse().enregistrerCodePostalClone(clone.getAdresse().getCodePostal());
                    client.enregistrerFormeClone(clone.getForme());
                    //Modification terminee
                } catch (CodePostalInexistantException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ClientSocieteInexistantException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                } catch (FormeMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                } catch (AdresseMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                } catch (CodePostalMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ZoneMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                }
        }
        
        public Vector<IClientSociete> listerClientsSociete()throws RemoteException {
                    Vector<IClientSociete> listeTmp = convertCltStoICltS(bo.ListeClients.getInstance().getLlisteClientSociete());
                    return listeTmp;
        }    
    
        public Vector<IClientSociete> rechercherClientSociete_NumClient(int numeroClient) throws RemoteException {
                Vector<IClientSociete> _lstCltS = new Vector<IClientSociete>();
                ClientSociete cltTmp = bo.ListeClients.getInstance().rechercherSocieteIdClient(numeroClient);
                if (cltTmp != null) 
                    _lstCltS.add(cltTmp);
                return _lstCltS;
        }

        public Vector<IClientSociete> rechercherClientSociete_NomSociete(String nomSociete) throws RemoteException {
                Vector<IClientSociete> _lstCltS = new Vector<IClientSociete>();
                ClientSociete cltTmp = bo.ListeClients.getInstance().rechercherSocieteNom(nomSociete);
                _lstCltS.add(cltTmp);
                return _lstCltS;
        }
     
        public Vector<IClientSociete> rechercherClientSociete_Adresse(  String rue, String numero, String codePostal,
                                                                        String commune) throws RemoteException {
                try {
                    Vector<IClientSociete> lstClientS = new Vector<IClientSociete>();
                    lstClientS = convertCltStoICltS(bo.ListeClients.getInstance().rechercherSocieteAdresse(rue, numero, codePostal, commune));
                    return lstClientS;
                } catch (AdresseMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                } catch (CodePostalMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }

        public Vector<IForme> listerFormes() throws RemoteException {
                try {
                    Vector<IForme> listeTmp = convertFrmtoIFrm(bo.Forme.lister());
                    return listeTmp;
                } catch (FormeInexistantException ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }
   
        //Client
        
        public Vector<ICodePostal> rechercherCP(String codePostal) throws RemoteException {
                try {
                    return convertCPtoICP(bo.CodePostal.listerCodePostaux(codePostal));
                } catch (Exception ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }

        public Vector<ICodePostal> rechercherCommune(String commune) throws RemoteException {
                try {
                    return convertCPtoICP(bo.CodePostal.listerCommunes(commune));
                } catch (Exception ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }
        
        public Vector<IAdresse> listerAdresseParClient(int idClient) throws RemoteException {
                try {
                    return convertAdressetoIAdresse(bo.Adresse.listerAdresseParClient(idClient));
                } catch (Exception ex) {
                    Logger.getLogger(GestionClients.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }
        
        public Vector<IIntervention> rechercherInterventionCloturee()throws RemoteException {
                throw new UnsupportedOperationException("Not supported yet.");
        }
}